package com.hspedu.furns.web;

import com.hspedu.furns.entity.Furn;
import com.hspedu.furns.entity.Page;
import com.hspedu.furns.service.FurnService;
import com.hspedu.furns.service.MemberService;
import com.hspedu.furns.service.impl.FurnServiceImpl;
import com.hspedu.furns.service.impl.MemberServiceImpl;
import com.hspedu.furns.utils.DataUtils;
import com.hspedu.furns.utils.WebUtils;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.UUID;

/**
 * @author 徐
 * @version 1.0
 */
public class FurnServlet extends BasicServlet {
    //定义一个service属性
    private FurnService furnService = new FurnServiceImpl();

    /**
     * 使用模板设计模式+反射+动态绑定调用furn方法
     *
     * @param request
     * @param response http://localhost:8080/jiaju_mall/manage/furnServlet?action=list
     */
    public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //System.out.println("FurnServlet list()被调用...");
        List<Furn> furns = furnService.queryFurns();
        //把furns集合放到request中
        request.setAttribute("furns", furns);
        //请求转发
        request.getRequestDispatcher("/views/manage/furn_manage.jsp").
                forward(request, response);
    }

    /**
     * 添加家居，调用service方法
     * 1.0版本
     * @param request
     * @param response
     */
//    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        //方式2，使用工具类，自动封装javaBean对象
//        Furn furn = DataUtils.copyParamToBean(request.getParameterMap(), new Furn());
//        //调用service
//        int i = furnService.addFurn(furn);
//        //执行成功，请求转发到家居显示页面
//        if (i == 1) {
//            //先查询所有的家居,可以是下面这种写法
//            //请求转发到家居显示页面
//            //request.getRequestDispatcher("/manage/furnServlet?action=list").forward(request,response);
//            //这里改成重定向，因为使用请求转发，当刷新页面时，会再次添加 刚添加 的家居信息
//            //重定向是发生在浏览器，我们回送的url最好是完整地
//            //response.sendRedirect(request.getContextPath() + "/manage/furnServlet?action=list");
//            response.sendRedirect(request.getContextPath() + "/manage/furnServlet?action=page&pageNo=" +
//                    request.getParameter("pageNo"));
//        } else {
//            request.setAttribute("msg", "添加家居失败，请重新添加");
//            request.getRequestDispatcher("/views/manage/furn_add.jsp").
//                    forward(request, response);
//        }
//    }

    /**
     * 删除单条家居信息
     *
     * @param request
     * @param response
     */
    public void delete(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
        //接收要删除的id,防止发生异常，封装成方法
        int id = DataUtils.parseInt(request.getParameter("id"), 0);
        //调用service
        int i = furnService.deleteFurnById(id);
        //再次查询家居信息-更新
        //response.sendRedirect(request.getContextPath() + "/manage/furnServlet?action=list");
        response.sendRedirect(request.getContextPath() +
                "/manage/furnServlet?action=page&pageNo=" + request.getParameter("pageNo"));
    }

    /**
     * 回显要修改的家居信息
     *
     * @param request
     * @param response
     */
    public void showFurn(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        //接收参数id
        String id = request.getParameter("id");
        int i = DataUtils.parseInt(id, 0);
        //调用service
        Furn furn = furnService.queryFurnById(i);
        //将查询到的家居对象信息添加到request域中
        request.setAttribute("furnMes", furn);
//        //将要修改家居所在的页码数，添加到request域中,用于修改之后，还在原页码上
//        request.setAttribute("pageNo",request.getParameter("pageNo"));
        //如果请求带来的参数 pageNo=1 , 而且是请求转发到下一个页面, 在下一个页面可以通过 param.pageNo
        //请求转发
        request.getRequestDispatcher("/views/manage/furn_update.jsp").
                forward(request, response);
    }

    /**
     * 修改家居信息
     * @param request
     * @param response
     */
//    public void update(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
//        //获取到页面发送的数据,使用工具类
//        Furn furn = DataUtils.copyParamToBean(request.getParameterMap(), new Furn());
//        //调用service
//        int i = furnService.updateFurn(furn);
//        //刷新最新的家居信息
//        //response.sendRedirect(request.getContextPath() + "/manage/furnServlet?action=list");
//        //这里考虑分页，带上pageNo信息
//        response.sendRedirect(request.getContextPath() +
//                "/manage/furnServlet?action=page&pageNo="+ request.getParameter("pageNo"));
//    }

    /**
     * 用于分页显示功能
     *
     * @param request
     * @param response
     */
    protected void page(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取传入的页码数
        int pageNo = DataUtils.parseInt(request.getParameter("pageNo"), 1);
        //获取每页显示数量
        int pageSize = DataUtils.parseInt(request.getParameter("pageSize"), Page.PAGE_SIZE);
        //调用service方法
        Page<Furn> page = furnService.page(pageNo, pageSize);
        //将本页的家居信息放到request域中
        request.setAttribute("page", page);
        //请求转发
        request.getRequestDispatcher("/views/manage/furn_manage.jsp").
                forward(request, response);

    }

    /**
     * 修改家居信息
     *
     * @param request
     * @param response 2.0版 + 图片修改上传功能
     *                 如果你的表单是enctype="multipart/form-data",
     *                 req.getParameter("id") 得不到id
     */
    public void update(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //将提交修改的家居信息，封装成Furn对象

        //如果你的表单是enctype="multipart/form-data", req.getParameter("id") 得不到id
        int id = DataUtils.parseInt(request.getParameter("id"), 0);
        //获取到对应furn对象[从db中获取]
        Furn furn = furnService.queryFurnById(id);
        //todoo 做一个判断 furn为空就不处理
        if (furn == null) {
            return;
        }
        //1. 判断是不是文件表单(enctype="multipart/form-data")
        if (ServletFileUpload.isMultipartContent(request)) {
            //2. 创建 DiskFileItemFactory 对象, 用于构建一个解析上传数据的工具对象
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            //3. 创建一个解析上传数据的工具对象

            ServletFileUpload servletFileUpload =
                    new ServletFileUpload(diskFileItemFactory);
            //解决接收到文件名是中文乱码问题
            servletFileUpload.setHeaderEncoding("utf-8");

            //4. 关键的地方, servletFileUpload 对象可以把表单提交的数据text / 文件
            //   将其封装到 FileItem 文件项中
            try {
                List<FileItem> list = servletFileUpload.parseRequest(request);
                //遍历，并分别处理=> 自然思路
                for (FileItem fileItem : list) {
                    //判断是不是一个文件=> 你是OOP程序员
                    if (fileItem.isFormField()) {//如果是true就是文本 input text(普通的表单字段)

                        if ("name".equals(fileItem.getFieldName())) {//家居名
                            furn.setName(fileItem.getString("utf-8"));
                        } else if ("maker".equals(fileItem.getFieldName())) {//制造商
                            furn.setMaker(fileItem.getString("utf-8"));
                        } else if ("price".equals(fileItem.getFieldName())) {//价格
                            furn.setPrice(new BigDecimal(fileItem.getString()));
                        } else if ("sales".equals(fileItem.getFieldName())) {//销量
                            furn.setSales(new Integer(fileItem.getString()));
                        } else if ("stock".equals(fileItem.getFieldName())) {//库存
                            furn.setStock(new Integer(fileItem.getString()));
                        }

                    } else {//是一个文件

                        //获取上传的文件的名字
                        String name = fileItem.getName();

                        //如果用户没有选择新的图片, name = ""
                        if (!"".equals(name)) {
                            //1.指定一个目录 , 就是我们网站工作目录下
                            String filePath = "/" + WebUtils.FURN_IMG_DIRECTORY;
                            //2. 获取到完整目录 [io/servlet基础]
                            String fileRealPath =
                                    request.getServletContext().getRealPath(filePath);

                            //3. 创建这个上传的目录=> 创建目录?=> Java基础
                            File fileRealPathDirectory = new File(fileRealPath + "\\" + WebUtils.getYearMonthDay());
                            if (!fileRealPathDirectory.exists()) {//不存在，就创建
                                fileRealPathDirectory.mkdirs();//创建
                            }

                            //4. 将文件拷贝到fileRealPathDirectory目录
                            //   构建一个上传文件的完整路径 ：目录+文件名
                            //   对上传的文件名进行处理, 前面增加一个前缀，保证是唯一即可, 不错
                            name = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + "_" + name;
                            String fileFullPath = fileRealPathDirectory + "/" + name;
                            fileItem.write(new File(fileFullPath)); //保存

                            fileItem.getOutputStream().close();//关闭流

                            //更新家居的图片路径
                            furn.setImgPath(WebUtils.FURN_IMG_DIRECTORY + "/" + WebUtils.getYearMonthDay() + name);
                            //todoo 删除原来旧的不用的图片
                            //在执行更改前，获取到图片路径
                            String furnImgPath = furnService.getFurnImgPath(id);
                            //删除图片所在路径
                            //File file = new File(fileRealPathDirectory + "\\"  + name);
                            //System.out.println(fileRealPathDirectory + "\\"  + name);

                            Path path = Paths.get(WebUtils.HEAD_IMG_DIRECTORY + furnImgPath);
                            System.out.println("要删除的家居图片路径 " + path);
                            boolean result = Files.deleteIfExists(path);
                            System.out.println(result ? "删除成功" : "删除失败");
                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("不是文件表单...");
        }

        //更新furn对象->DB
        furnService.updateFurn(furn);
        //可以请求转发到更新成功的页面..
        request.getRequestDispatcher("/views/manage/update_ok.jsp").forward(request, response);
    }

    /**
     * v2.0 添加家居可选择图片添加
     *
     * @param request
     * @param response
     * @throws ServletException
     * @throws IOException
     */
    public void add(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //创建furn对象
        Furn furn = new Furn();

        //1. 判断是不是文件表单(enctype="multipart/form-data")
        if (ServletFileUpload.isMultipartContent(request)) {
            //2. 创建 DiskFileItemFactory 对象, 用于构建一个解析上传数据的工具对象
            DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
            //3. 创建一个解析上传数据的工具对象

            ServletFileUpload servletFileUpload =
                    new ServletFileUpload(diskFileItemFactory);
            //解决接收到文件名是中文乱码问题
            servletFileUpload.setHeaderEncoding("utf-8");

            //4. 关键的地方, servletFileUpload 对象可以把表单提交的数据text / 文件
            //   将其封装到 FileItem 文件项中
            try {
                List<FileItem> list = servletFileUpload.parseRequest(request);
                //遍历，并分别处理=> 自然思路
                for (FileItem fileItem : list) {
                    //判断是不是一个文件
                    if (fileItem.isFormField()) {//如果是true就是文本 input text(普通的表单字段)

                        if ("name".equals(fileItem.getFieldName())) {//家居名
                            furn.setName(fileItem.getString("utf-8"));
                        } else if ("maker".equals(fileItem.getFieldName())) {//制造商
                            furn.setMaker(fileItem.getString("utf-8"));
                        } else if ("price".equals(fileItem.getFieldName())) {//价格
                            furn.setPrice(new BigDecimal(fileItem.getString()));
                        } else if ("sales".equals(fileItem.getFieldName())) {//销量
                            furn.setSales(new Integer(fileItem.getString()));
                        } else if ("stock".equals(fileItem.getFieldName())) {//库存
                            furn.setStock(new Integer(fileItem.getString()));
                        }

                    } else {//是一个文件

                        //获取上传的文件的名字
                        String name = fileItem.getName();

                        //如果用户没有选择新的图片, name = ""
                        if (!"".equals(name)) {
                            //1.指定一个目录 , 就是我们网站工作目录下
                            String filePath = "/" + WebUtils.FURN_IMG_DIRECTORY;
                            //2. 获取到完整目录 [io/servlet基础]
                            String fileRealPath =
                                    request.getServletContext().getRealPath(filePath);

                            //3. 创建这个上传的目录=> 创建目录?=> Java基础
                            File fileRealPathDirectory = new File(fileRealPath + "\\" + WebUtils.getYearMonthDay());
                            if (!fileRealPathDirectory.exists()) {//不存在，就创建
                                fileRealPathDirectory.mkdirs();//创建
                            }

                            //4. 将文件拷贝到fileRealPathDirectory目录
                            //   构建一个上传文件的完整路径 ：目录+文件名
                            //   对上传的文件名进行处理, 前面增加一个前缀，保证是唯一即可, 不错
                            name = UUID.randomUUID().toString() + "_" + System.currentTimeMillis() + "_" + name;
                            String fileFullPath = fileRealPathDirectory + "/" + name;
                            fileItem.write(new File(fileFullPath)); //保存

                            fileItem.getOutputStream().close();//关闭流

                            //更新家居的图片路径
                            furn.setImgPath(WebUtils.FURN_IMG_DIRECTORY + "/" + WebUtils.getYearMonthDay() + name);

                        }
                    }
                }

            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("不是文件表单...");
        }

        //调用service
        int i = furnService.addFurn(furn);
        //执行成功，请求转发到家居显示页面
        if (i == 1) {
            //这里改成重定向，因为使用请求转发，当刷新页面时，会再次添加 刚添加 的家居信息
            response.sendRedirect(request.getContextPath() + "/manage/furnServlet?action=page&pageNo=" +
                    request.getParameter("pageNo"));
        } else {
            request.setAttribute("msg", "添加家居失败，请重新添加");
            request.getRequestDispatcher("/views/manage/furn_add.jsp").
                    forward(request, response);
        }

    }
}
